package org.data.replay.common;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.io.Serializable;

/**
 * 统一响应结果封装类 用于统一API接口的返回格式，包含以下字段：
 *
 * @author DataReplay
 */
@Data
@ApiModel(value = "接口返回对象", description = "统一接口返回格式")
public class Result<T> implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    /**
     * 成功标志 true: 操作成功, false: 操作失败
     */
    @ApiModelProperty(value = "成功标志")
    private boolean success = true;
    
    /**
     * 返回处理消息 用于描述操作结果的具体信息，如成功提示或错误描述
     */
    @ApiModelProperty(value = "返回处理消息")
    private String message = "操作成功";
    
    /**
     * 返回代码 200: 成功 400: 请求参数错误 401: 未授权 403: 禁止访问 404: 资源不存在 500: 服务器错误
     */
    @ApiModelProperty(value = "返回代码")
    private Integer code = 200;
    
    /**
     * 返回数据对象（标准字段） 泛型T，可以是任意类型的数据，如List、Map、实体对象等 当操作失败时，通常为null
     */
    @ApiModelProperty(value = "返回数据对象")
    private T result;
    
    /**
     * 返回数据对象（兼容字段，与data为同一值） 为了兼容旧代码可能使用result字段，通过getter/setter映射
     */
    @ApiModelProperty(value = "返回数据对象（兼容字段）")
    @JsonProperty("result")
    public T getResult() {
        return result;
    }
    
    @JsonProperty("result")
    public void setResult(T result) {
        this.result = result;
    }
    
    /**
     * 时间戳 记录接口响应时间，用于调试和日志记录 格式: 毫秒级时间戳
     */
    @ApiModelProperty(value = "时间戳")
    private long timestamp = System.currentTimeMillis();
    
    /**
     * 在线表单标识 用于标识是否为在线表单相关的请求 该字段不参与JSON序列化
     */
    @JsonIgnore
    private String onlTable;
    
    // ==================== 构造函数 ====================
    
    /**
     * 默认构造函数 创建成功状态的Result对象，使用默认值
     */
    public Result() {
    }
    
    /**
     * 私有构造函数，用于静态工厂方法
     */
    private Result(boolean success, Integer code, String message, T result) {
        this.success = success;
        this.code = code;
        this.message = message;
        this.result = result;
        this.timestamp = System.currentTimeMillis();
    }
    
    // ==================== 成功响应方法 ====================
    
    /**
     * 创建成功响应（无数据）
     *
     * @param <T> 数据类型
     * @return 成功状态的Result对象
     */
    public static <T> Result<T> success() {
        return new Result<>(true, 200, "操作成功", null);
    }
    
    /**
     * 创建成功响应（带数据）
     *
     * @param <T>  数据类型
     * @param data 返回数据
     * @return 成功状态的Result对象
     */
    public static <T> Result<T> success(T data) {
        return new Result<>(true, 200, "操作成功", data);
    }
    
    /**
     * 创建成功响应（自定义消息）
     *
     * @param <T>     数据类型
     * @param message 成功消息
     * @return 成功状态的Result对象
     */
    public static <T> Result<T> success(String message) {
        return new Result<>(true, 200, message, null);
    }
    
    /**
     * 创建成功响应（自定义消息和数据）
     *
     * @param <T>     数据类型
     * @param message 成功消息
     * @param data    返回数据
     * @return 成功状态的Result对象
     */
    public static <T> Result<T> success(String message, T data) {
        return new Result<>(true, 200, message, data);
    }
    
    /**
     * 创建成功响应（自定义状态码、消息和数据）
     *
     * @param <T>     数据类型
     * @param code    状态码
     * @param message 成功消息
     * @param data    返回数据
     * @return 成功状态的Result对象
     */
    public static <T> Result<T> success(Integer code, String message, T data) {
        return new Result<>(true, code, message, data);
    }
    
    // ==================== 错误响应方法 ====================
    
    /**
     * 创建错误响应（默认状态码500）
     *
     * @param message 错误消息
     * @return 错误状态的Result对象
     */
    public static <T> Result<T> error(String message) {
        return new Result<>(false, 500, message, null);
    }
    
    /**
     * 创建错误响应（自定义状态码）
     *
     * @param code    错误状态码
     * @param message 错误消息
     * @return 错误状态的Result对象
     */
    public static <T> Result<T> error(Integer code, String message) {
        return new Result<>(false, code, message, null);
    }
    
    /**
     * 创建错误响应（自定义状态码、消息和数据）
     *
     * @param <T>     数据类型
     * @param code    错误状态码
     * @param message 错误消息
     * @param data    返回数据
     * @return 错误状态的Result对象
     */
    public static <T> Result<T> error(Integer code, String message, T data) {
        return new Result<>(false, code, message, data);
    }
    
    /**
     * 创建错误响应（带数据，默认状态码500）
     *
     * @param <T>     数据类型
     * @param message 错误消息
     * @param data    返回数据
     * @return 错误状态的Result对象
     */
    public static <T> Result<T> error(String message, T data) {
        return new Result<>(false, 500, message, data);
    }
    
    // ==================== 便捷方法 ====================
    
    /**
     * 创建无权限访问错误响应（403）
     *
     * @param message 错误消息
     * @return 无权限错误状态的Result对象
     */
    public static <T> Result<T> forbidden(String message) {
        return new Result<>(false, 403, message, null);
    }
    
    /**
     * 创建未授权错误响应（401）
     *
     * @param message 错误消息
     * @return 未授权错误状态的Result对象
     */
    public static <T> Result<T> unauthorized(String message) {
        return new Result<>(false, 401, message, null);
    }
    
    /**
     * 创建资源不存在错误响应（404）
     *
     * @param message 错误消息
     * @return 资源不存在错误状态的Result对象
     */
    public static <T> Result<T> notFound(String message) {
        return new Result<>(false, 404, message, null);
    }
    
    /**
     * 创建请求参数错误响应（400）
     *
     * @param message 错误消息
     * @return 请求参数错误状态的Result对象
     */
    public static <T> Result<T> badRequest(String message) {
        return new Result<>(false, 400, message, null);
    }
    
    // ==================== 实例方法（链式调用） ====================
    
    /**
     * 设置成功状态
     *
     * @param message 成功消息
     * @return 当前Result对象，支持链式调用
     */
    public Result<T> withSuccess(String message) {
        this.success = true;
        this.code = 200;
        this.message = message;
        return this;
    }
    
    /**
     * 设置错误状态
     *
     * @param message 错误消息
     * @return 当前Result对象，支持链式调用
     */
    public Result<T> withError(String message) {
        this.success = false;
        this.code = 500;
        this.message = message;
        return this;
    }
    
    /**
     * 设置错误状态（自定义状态码）
     *
     * @param code    错误状态码
     * @param message 错误消息
     * @return 当前Result对象，支持链式调用
     */
    public Result<T> withError(Integer code, String message) {
        this.success = false;
        this.code = code;
        this.message = message;
        return this;
    }
    
    /**
     * 设置数据
     *
     * @param data 返回数据
     * @return 当前Result对象，支持链式调用
     */
    public Result<T> withResult(T data) {
        this.result = data;
        return this;
    }
    
    // ==================== 兼容方法（保持向后兼容） ====================
    
    /**
     * 创建成功响应（兼容方法，使用ok命名）
     *
     * @param <T> 数据类型
     * @return 成功状态的Result对象
     */
    public static <T> Result<T> ok() {
        return success();
    }
    
    /**
     * 创建成功响应（兼容方法，使用ok命名）
     *
     * @param <T>  数据类型
     * @param data 返回数据
     * @return 成功状态的Result对象
     */
    public static <T> Result<T> ok(T data) {
        return success(data);
    }
    
    /**
     * 创建成功响应（兼容方法，使用ok命名）
     *
     * @param <T>     数据类型
     * @param message 成功消息
     * @param data    返回数据
     * @return 成功状态的Result对象
     */
    public static <T> Result<T> ok(String message, T data) {
        return success(message, data);
    }
    
    /**
     * 创建无权限错误响应（兼容方法）
     *
     * @param message 错误消息
     * @return 无权限错误状态的Result对象
     */
    public static <T> Result<T> noauth(String message) {
        return forbidden(message);
    }
}
